#ifndef _MP3DECODER_H_
#define _MP3DECODER_H_

#include "decoder_conf.h"
#include <cstdint>
#include <cstddef>

#include "mad.h"

class MP3Decoder
{

public:
    ~MP3Decoder();

    bool open(const char *path);

    uint8_t *readDecodeFrame();
    void setCurrent(uint32_t _destSec);

    void close(void);

    int16_t getCurrrentSec(void) { return currentSec; }
    uint16_t getTotalSec(void) { return totalSec; }
    uint32_t getRate(void)  { return sampleRate; }
    uint8_t getChannels(void) { return nchannels; }
    uint16_t getFrameSize(void) { return pcmBufferFrameSize; }

private:
    void *decodeThread; // MP3解码线程
    void *dataReadySem;     // 数据就绪信号量(可以获取解码后的数据)
    void *decodeReadySem;  // 解码就绪信号量(可以进行下一帧解码)

    void *decoder; // libmad解码器

    uint8_t *buffer;    // 原始数据缓冲区
    size_t length;      // 原始数据总长度(文件大小)
    void *file = nullptr;         // 文件指针

    uint8_t *pcmBuffer;      // 解码后的pcm数据缓存区
    uint16_t pcmBufferFrameSize; // pcm数据缓存区数据帧大小

    uint16_t totalSec;   // 整首歌时长,单位:秒
    int16_t currentSec;     // 当前播放时间点
    int16_t destSec; // 目标时间点，用于设置播放时间点

    uint32_t sampleRate; // 采样率

    uint64_t durationFrac;
    uint64_t timelapseFrac;

    uint16_t durationSec;
    uint16_t timelapseSec;

    uint8_t nchannels;  // 通道数量;1,表示单声道;2,表示双声道;

    bool decodeThreadState;   // 解码线程状态(false - 线程不存在或已退出)、(true - 线程正在运行)
    bool destSeted;     // 进度调整标志

    int decodePreprocess(void);

    friend void mp3DecodeThreadFunc(void *arg);
    friend enum mad_flow header_preprocess(void *userData, struct mad_header const *header);
    friend enum mad_flow input(void *userData, struct mad_stream *stream);
    friend enum mad_flow header(void *userData, struct mad_header const *header);
    friend enum mad_flow output(void *userData, struct mad_header const *header, struct mad_pcm *pcm);
};

#endif
